#include "./../inc/bmp.hpp"

using namespace std;

BMP::BMP(string path, int width, int height)
{
    this->path = path;
    bmp_height = height;
    bmp_width = width;
    buf = new int[width * height * sizeof(int)];

    getBMP();
}

void BMP::getBMP()
{
    FILE *fp = fopen(path.data(), "rb");
    if (fp == NULL)
    {
        perror("BMP_fopen");
        return;
    }
    printf("open file [%s] bmp success\n", path.data());

    fseek(fp, 54, SEEK_SET);

    char buf_bmp[bmp_height][bmp_width * 3];

    memset(buf_bmp, 0, bmp_height * bmp_width * 3);

    int padding = (4 - (bmp_height * 3) % 4) % 4; // 计算每行填充字节数

    // 逐行读取 bmp图片每一行的字节数必须是4的倍数
    for (int i = 0; i < bmp_height; i++)
    {
        fread(buf_bmp[i], bmp_width * 3, 1, fp);
        if (padding > 0)
        {
            fseek(fp, padding, SEEK_CUR); // 跳过填充字节
        }
    }
    fclose(fp);

    // 处理像素数据，BMP是从下到上存储的
    for (int i = 0; i < bmp_height; i++)
    {
        int cow = bmp_height - i - 1; // 翻转Y坐标
        for (int j = 0; j < bmp_width; j++)
        {
            // 注意：BMP存储顺序是BGR
            int b = buf_bmp[i][j * 3];
            int g = buf_bmp[i][j * 3 + 1];
            int r = buf_bmp[i][j * 3 + 2];

            // 组合成32位ARGB格式（Alpha=0）
            buf[cow * bmp_width + j] = (0x00 << 24) | (r << 16) | (g << 8) | b;
        }
    }
}

void BMP::showBMP(LCD &lcd, int x, int y)
{
    int *lcd_mmap = lcd.get_lcd_mmap();
    if (!lcd_mmap)
    {
        printf("get lcd mmap failed\n");
        return;
    }

    if (x < 0 || y < 0 || x + bmp_width > lcd.get_lcd_width() || y + bmp_height > lcd.get_lcd_height())
    {
        printf("BMP position out of bounds\n");
        return;
    }

    // 正确计算LCD坐标
    for (int i = 0; i < bmp_height; i++)
    {
        for (int j = 0; j < bmp_width; j++)
        {
            // LCD坐标计算：y坐标 * LCD宽度 + x坐标
            lcd_mmap[(y + i) * lcd.get_lcd_width() + (x + j)] = buf[i * bmp_width + j];
        }
    }
}